﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace DirectX_CS
{
	/// <summary>
	/// RegistrationInfo class:
	/// Better than a struct, to keep some info private from each PrimitiveGenerator, 
	///  but still being associated with the class instances themselves.
	/// Only one copy of this class per registered primitiveWithVertices generator (PrimitiveGenerator)
	///
	/// I needed a way to keep it private to its derived class (because the base class is public);
	/// So I decided to keep (as of today) a Dictionary which can cross reference the info with the PrimitiveGenerator instance... 
	///  see declaration of Dictionary below. This ensures that:
	///  * You don't try change any values inadvertantly, etc..
	///     I'd refer you to google "class inheritance" or "C# access specifiers".
	///     Honestly it really came down to making things private to the derived class,
	///     yet being able to have access to it in another class (the PrimitiveRenderer).
	///     
	///  * This program still functions reliably if you say don't know how it works and try
	///    tinkering until it works. In other words its private to the PrimitiveRenderer class for a reason.
	///    Sure it adds perhaps unnecessary complexity but not much considering 
	///     breaking all rules and making it public and hoping it doesn't get changed is not all that 
	///     good either.
	/// </summary>
	public class RegistrationInfo
	{
		//public bool RegisteredIndexBuffer = false;
		public bool VertexRenderingEnabled 
		{
			get { if (vertexBufferObject == null)
					return false;
				else 
					return vertexBufferObject.EnableCallRenderPrimitives;
			}
			//set { vertexBufferObject.EnableCallRenderPrimitives = value; }
		}

		public bool IndexRenderingEnabled
		{
			get 
			{
				if (indexedBufferObject != null)
					return indexedBufferObject.EnableCallRenderIndexedPrimitives;
				else
					return false;
			}
			//set
			//{
			//    if (indexedBufferObject != null)
			//        indexedBufferObject.EnableCallRenderIndexedPrimitives = value;
			//}
		}

		public bool VertexBufferChanged = false;
		public bool IndexBufferChanged = false;

		//Set your vertex format to the type in use. 
		//This is a common source of error if you change my RV struct (in CustomVertex.cs) 
		// then be sure to change the constant too.

		public int CurrentVertexBufferLength = 0;
		public int CurrentIndexBufferLength = 0;

		//public int LockOffsetIntoVertexBuffer = -1; //allow negative until i get about making sure these get set right, the zero will work
		//public int LockOffsetIntoIndexBuffer = -1;

        //public SVector[] VertexData = null;
        //public int[] IndexData = null;
        public object GetIndices()
        {
            if (indexedBufferObject != null)
                return indexedBufferObject.GetIndices();
            else
                return null;
        }
        private IndexBuffer indexBuffer = null;
        public IndexBuffer IndexBuffer
        {
            get { return indexBuffer; }
            set { indexBuffer = value; }
        }

		public Array VertexPersistantBuffer;
		public Array IndexPersistantBuffer;

        public Array GetVertices()
        {
            return vertexBufferObject.GetVertices();
        }
        public int GetVerticesCount()
        {
			return vertexBufferObject.GetVerticesCount();
        }
		protected int mVertexDataLength = -1;
		protected int mIndexCopyLength = -1;
		
		public int VertexCopyLength
		{
			get { 
				return mVertexDataLength;
			}
			set { mVertexDataLength = value;}
		}

		public int IndexCopyLength
		{
			get {
				return mIndexCopyLength;
			}
			set { mIndexCopyLength = value; }
		}
		
		//public int InitialLength = 0; //not used if UseExactLength is true
		//public int ScaleFactor = 2;//not used if UseExactLength is true
		//public long MaxLength = 0; //if decide to implement, if data grows over maxlength data becomes "dynamic"

		//Note if the array changes by one element the entire vertex buffer will need to be redone.
		//public bool DoNotBuffer = false; //InitialLength ScaleFactor not used if UseExactLength is true. 


		/// <summary>
		/// BEGIN: POSSIBLE FUTURE IMPLEMENATION OF AUTOMATIC PRIMITIVE RENDERING LISTS.
		/// </summary>
		//protected PrimitiveType primitiveType = PrimitiveType.PointList;
		//zero is ok initially, however it should reflect the .Length of PrimitiveGenerator's returned array of struct "CustomVertex" 
		//find all references to this and make sure that they get changed before used.
		//public int PrimitiveCount = 0;
		//be sure that they get set to something to your liking otherwise you'll just list some points on the screen to draw.
		//find all references to this and make sure they get changed before used.
		//public PrimitiveType PrimitiveType = PrimitiveType.PointList;

		//public Matrix PreModelTransform;

		/// <summary>
		/// END OF AUTOMATIC PRIMITIVE RENDERING LIST IDEAS.
		/// </summary>

		public RegistrationInfo()
		{
		}
		public RegistrationInfo(object pg)
		{
			PrimitiveObject = pg;
		}
		private object thePrimitive;

		public object PrimitiveObject
		{
			get { return thePrimitive; }
			set { thePrimitive = value; }
		}

		protected IManagedVertexBuffer vertexBufferObject = null;

		public IManagedVertexBuffer VertexBufferObject
		{
			get { return vertexBufferObject; }
			set { vertexBufferObject = value; }
		}

		protected IManagedIndexBuffer indexedBufferObject = null;

		public IManagedIndexBuffer IndexedBufferObject
		{
			get { return indexedBufferObject; }
			set { indexedBufferObject = value; }
		}

		//protected IManagedModelView renderHelper = null;
		//public IManagedModelTransformable RenderHelper
		//{
		//    get { return renderHelper; }
		//    set { renderHelper = value; }
		//}
        
        private VertexBuffer vertexBuffer = null;

        public VertexBuffer VertexBuffer
        {
            get { return vertexBuffer; }
            set { vertexBuffer = value; }
        }

        //private int GetNewVBLength(int oldVBLength)
        //{
        //    return ScaleFactor * oldVBLength;
        //}

        //public int MemoryRemaining()
        //{
        //    return CurrentVertexBufferLength - VertexCopyLength;
        //}

		/// <summary>
		/// Only reason I think that this will return true is if the PrimitiveGenerator was unregistered.
		/// It will then have been set to null. To prevent regenerating the data when a generator 
		/// goes unused for example, we just set to null the associated info member.
		/// </summary>
		/// <returns></returns>
		public bool WasUnRegistered()
		{
			return (PrimitiveObject == null);
		}

        private bool mIsIBInitialized = false;
        public bool IsIBInitialized
        {
            get
            {
				return mIsIBInitialized;
            }
            set
            {
				mIsIBInitialized = value;
            }
        }

        private bool mIsInitialized = false;
        public bool IsInitialized
        {
            get 
            {
				return mIsInitialized;
            }
			set
			{
				mIsInitialized = value;
			}
        }

        private bool useManagedMaterial = false;

        public bool UseManagedMaterial
        {
            get { return useManagedMaterial; }
            set { useManagedMaterial = value; }
        }
        private bool useSimpleManagedModelView = false;

        public bool UseManagedModelView
        {
            get { return useSimpleManagedModelView; }
            set { useSimpleManagedModelView = value; }
        }

	}   //end of struct
}       //end of namespace.
